package com.lokyiu.mybible.wol;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

public class InputStreamDocumentFactory implements DocumentFactory {

	private InputStream is;

	public InputStreamDocumentFactory(InputStream is) {
		this.is = is;
	}

	public void setInputStream(InputStream is) {
		this.is = is;
	}

	private byte[] byteArray;
	private InputStream reuseableInputStream;

	@Override
	public Document getDocument() {
		if (byteArray == null) {
			byte[] buff = new byte[8000];

			int bytesRead = 0;

			ByteArrayOutputStream bao = new ByteArrayOutputStream();
			try {
				while ((bytesRead = is.read(buff)) != -1) {
					bao.write(buff, 0, bytesRead);
				}
				byteArray = bao.toByteArray();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		reuseableInputStream = new ByteArrayInputStream(byteArray);
		Document doc = null;
		try {
			doc = (Document) Jsoup.parse(reuseableInputStream, "UTF-8", "http://wol.jw.org");
		} catch (SocketTimeoutException ste) {
			// Timed out, so retry 3 times
			System.err.println("Timed out, so retrying 1...");
			doc = retryGetDocument(is, 0);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return doc;
	}

	/**
	 * This method performs the retry. Called from getDocument(String). DON'T
	 * call directly.
	 * 
	 * @param url
	 * @param retryNo
	 * @return
	 */
	private Document retryGetDocument(InputStream is, int retryNo) {
		Document doc = null;
		if (retryNo < 3) {
			try {
				doc = (Document) Jsoup.parse(is, "UTF-8", "http://wol.jw.org");
			} catch (SocketTimeoutException ste) {
				// Timed out again, so retry
				System.out.println("Timed out again, retry " + retryNo);
				doc = retryGetDocument(is, retryNo++);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			System.err.println("Retried 3 times, so aborting...");
		}
		return doc;
	}

}
